﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Configuration;

namespace Vote.Web.Common
{
    /// <summary>
    /// 验证登录
    /// </summary>
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
    public class AuthorizationAttribute : FilterAttribute, IAuthorizationFilter
    {

        private String _AuthUrl = String.Empty;
        private String _AuthSaveKey = String.Empty;
        public String _AuthSaveType = String.Empty;


        public String AuthUrl
        {
            get { return _AuthUrl; }
            set { _AuthUrl = value; }
        }
        public String AuthSaveKey
        {
            get { return _AuthSaveKey; }
            set { _AuthSaveKey = value; }
        }
        public String AuthSaveType
        {
            get { return _AuthSaveType; }
            set { _AuthSaveType = value; }
        }

        /// <summary>
        /// 默认构造函数
        /// </summary>
        public AuthorizationAttribute()
        {
            this._AuthUrl = ConfigurationManager.AppSettings["AuthUrl"];
            this._AuthSaveKey = ConfigurationManager.AppSettings["AuthSaveKey"];
            this._AuthSaveType = ConfigurationManager.AppSettings["AuthSaveType"];
        }

        /// <summary>
        /// 重载构造函数
        /// </summary>
        /// <param name="authUrl">表示没有登录跳转的登录地址</param>
        public AuthorizationAttribute(String authUrl)
        {
            this._AuthUrl = authUrl;
        }

        /// <summary>
        /// 重载构造函数
        /// </summary>
        /// <param name="authUrl">表示没有登录跳转的登录地址</param>
        /// <param name="saveKey">表示登录用来保存登陆信息的键名</param>
        public AuthorizationAttribute(String authUrl, String saveKey):this(authUrl)
        {
            this.AuthSaveKey = saveKey;
            this.AuthSaveType = "SESSION";
        }

        /// <summary>
        /// 重载构造函数
        /// </summary>
        /// <param name="authUrl">表示没有登录跳转的登录地址</param>
        /// <param name="saveKey">表示登录用来保存登陆信息的键名</param>
        /// <param name="saveType">表示登录用来保存登陆信息的方式</param>
        public AuthorizationAttribute(String authUrl, String saveKey, String saveType):this(authUrl,saveKey)
        {
            this._AuthSaveType = saveType;
        }


        public void OnAuthorization(AuthorizationContext filterContext)
        {
            if (null == filterContext.HttpContext)
            {
                throw new Exception(this.ToString() + "此特性只适合于Web应用程序使用！");
            }
            else
            {
                switch (AuthSaveType)
                {
                    case "SESSION":
                        if (null == filterContext.HttpContext.Session)
                        {
                            throw new Exception("服务器Session不可用");
                        }
                        else if (!filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true) &&
                            !filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true))
                        {
                            if (null == filterContext.HttpContext.Session[_AuthSaveKey])
                            {
                                filterContext.Result = new RedirectResult(_AuthUrl);
                            }
                        }
                        break;
                    case "COOKIE":
                        if (!filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true) &&
                            !filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true))
                        {
                            if (null == filterContext.HttpContext.Request.Cookies[_AuthSaveKey])
                            {
                                filterContext.Result = new RedirectResult(_AuthUrl);
                            }
                        }
                        break;
                    default:
                        throw new ArgumentNullException("用于保存登陆信息的方式不能为空，只能为Cookie或者Session！");
                }
            }
        }

    }
}